package main

func main() {

}

type MyCircularQueue struct {
	vals  []int
	front int
	tail  int
}

func Constructor(k int) MyCircularQueue {
	return MyCircularQueue{
		vals:  make([]int, k+1),
		front: 0,
		tail:  0,
	}
}

func (this *MyCircularQueue) EnQueue(value int) bool {
	if this.IsFull() {
		return false
	}
	this.vals[this.tail] = value
	this.tail = (this.tail + 1) % len(this.vals)
	return true
}

func (this *MyCircularQueue) DeQueue() bool {
	if this.IsEmpty() {
		return false
	}
	this.front = (this.front + 1) % len(this.vals)
	return true
}

func (this *MyCircularQueue) Front() int {
	if this.IsEmpty() {
		return -1
	}
	return this.vals[this.front]
}

func (this *MyCircularQueue) Rear() int {
	if this.IsEmpty() {
		return -1
	}
	var tail int
	if this.tail == 0 {
		tail = len(this.vals) - 1
	} else {
		tail = this.tail - 1
	}
	return this.vals[tail]
}

func (this *MyCircularQueue) IsEmpty() bool {
	return this.tail == this.front
}

func (this *MyCircularQueue) IsFull() bool {
	return (this.tail+1)%len(this.vals) == this.front
}

/**
 * Your MyCircularQueue object will be instantiated and called as such:
 * obj := Constructor(k);
 * param_1 := obj.EnQueue(value);
 * param_2 := obj.DeQueue();
 * param_3 := obj.Front();
 * param_4 := obj.Rear();
 * param_5 := obj.IsEmpty();
 * param_6 := obj.IsFull();
 */
